home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr48 / 386p_200.zip / 386JOY.ASM < prev    next >
Assembly Source File  |  1995-01-14  |  13KB  |  541 lines

  1. ; Joystick control module
  2. ;  <bashing mode on>
  3. ;   Grrr! Why those wimpy IBM engineers chosed a stupid analog interface ?!?!?
  4. ;   Heck! If at least they included enough hardware support this 
  5. ;   could have been a little problem, but ...argh!... 
  6. ;   I hate polling things when lots of IRQs keeps knocking on the P.I.C. !!!!
  7. ;   Of course this is the "default stick" handling code, if you plan to
  8. ;   add cooler sticks, just write a XID driver and let it take control.
  9. ; <bashing mode off>
  10. ;
  11. ; Well, this is my "safe" joystick handling code
  12. ; there are better ways to handle sticks, but i know this works on anything
  13.  
  14. ; _InitStick
  15. ; _ReadStick
  16.  
  17. .386P
  18.  
  19. code32 segment para public use32
  20.        assume cs:code32,ds:code32
  21. include 386power.inc
  22. include 386video.inc
  23. include pix.inc
  24. include chario.inc
  25. include 386keyb.inc
  26. include 386menu.inc
  27.  
  28. ; What is needed to read the joystick port:
  29. ;1.  Trigger the joystick oneshots with an 'out' to 0x201.
  30. ;    This will set all of the joystick bits on.
  31.  
  32. ;2.  Read (in) 0x201, finding:
  33.  
  34. ;     Bit         Contents
  35. ;     0         Joystick A X coordinate
  36. ;     1         Joystick A Y coordinate
  37. ;     2         Joystick B X coordinate
  38. ;     3         Joystick B Y coordinate
  39. ;     4         Button A 1
  40. ;     5         Button A 2
  41. ;     6         Button B 1
  42. ;     7         Button B 2
  43. ;
  44. ;3.  Continue reading 0x201 until ALL oneshots return to zero
  45. ;    (i've seen lots of joystic routines that seems to miss this)
  46. ;    recording the loop during which each bit falls to zero.
  47. ;    The duration of the pulse from each oneshot may be used to
  48. ;    determine the resistive load (from 0 to 100K) from each
  49. ;    Joystick, as: Time = 24.2msec. + .011 (r) msec.
  50. ;
  51. ;4.  To do this correctly, I recommend calibrating the joystick;
  52. ;    have the user move the stick to each corner, then center it,
  53. ;    while recording the resulting values.
  54.  
  55.       align dword
  56. ; the following DWORDS the "downcount value" reached when
  57. ; the corresponding bit in the joystick port
  58. ; has gone under the "logic 1" threshold value.
  59. _JX_A dd 0
  60. _JY_A dd 0
  61. _JX_B dd 0
  62. _JY_B dd 0
  63. _B1_A dd 0
  64. _B2_A dd 0
  65. _B1_B dd 0
  66. _B2_B dd 0
  67.  
  68. ; calibration parameters for joystick A
  69. A_YUP     dd 0
  70. A_XLEFT   dd 0
  71. A_YCENTER dd 0
  72. A_XCENTER dd 0
  73. A_YDOWN   dd 0
  74. A_XRIGHT  dd 0
  75.  
  76.  
  77. ; calibration parameters for joystick B
  78. B_YUP     dd 0
  79. B_XLEFT   dd 0
  80. B_YCENTER dd 0
  81. B_XCENTER dd 0
  82. B_YDOWN   dd 0
  83. B_XRIGHT  dd 0
  84.  
  85. _BUTTON         dd 0
  86.  
  87. _POLL_TIME      dd 00000FFFFh ; usually this is fast enough
  88.         ; MAX. NUMBER OF LOOPS WE HAVE TO PERFORM
  89.         ; TO COMPLETELY DECODE THE JOYSTICK PORT
  90.                 ; (during calibration it will be set to the higher
  91.                 ;  "poll" value to speed up joystick reads)
  92.  
  93. JPORT    equ 0201h
  94.  
  95.        ; MAX. 30 chars for every name
  96. IBMStick db 'plain joystick',0
  97.  
  98.        ; joysticks name table
  99.        public _StickName
  100. _StickName dd offset IBMStick
  101.            dd 0,0,0
  102.  
  103.        ; check joystick
  104. SOK    dd offset OkMIStick,offset snone,offset snone,offset snone
  105.  
  106.        ; init stick table
  107. IStick dd offset MIStick, offset snone, offset snone, offset snone
  108.  
  109.         align byte
  110.         public _StickOK
  111. _StickOK:
  112.         jmp [esi*4+SOK]
  113.  
  114. OkMIStick:
  115.         stc
  116.         ret
  117.  
  118.         public _InitStick
  119. _InitStick:
  120.         jmp [esi*4+IStick]
  121.  
  122. nojoys  db 'XID: Invalid joystick device',CR,LF,'$'
  123. snone:  mov _386Return,offset nojoys
  124.         jmp _Exit
  125.  
  126. head   db '   pc joystick calibration   ',0
  127. tail   db '      and press a button     ',0        
  128.  
  129. center  db 'MOVE TO   CENTRAL   POSITION',0
  130. upleft  db 'MOVE TO UPPER LEFT  POSITION',0
  131. dnright db 'MOVE TO LOWER RIGHT POSITION',0
  132. xug db ' x_1=',0
  133.     db ' y_1=',0
  134.     db ' x_2=',0
  135.     db ' y_2=',0
  136.     db 'b0_1=',0
  137.     db 'b1_1=',0
  138.     db 'b0_2=',0
  139.     db 'b1_2=',0
  140.    
  141.  
  142. ctr1 dd 0
  143. ctr2 dd 0
  144. Shuu:
  145.         pushad
  146.         mov edi,_ScrBase
  147.         mov eax,_VDispX
  148.         mov esi,offset _JX_A
  149.         mov ctr1,2
  150.         add eax,6*8
  151. luup1:        
  152.         mov edx,_VDispY
  153.         add edx,100
  154.         mov ctr2,4
  155. luup2:        
  156.         mov ebx,[esi]
  157.         add esi,4
  158.         mov ecx,8
  159.         call _PutUnsigned
  160.         mov ecx,16
  161.         mov ebx,8
  162.         sub eax,_VDispX
  163.         sub edx,_VDispY
  164.         call _TouchBlock
  165.         add eax,_VDispX
  166.         add edx,_VDispY
  167.         add edx,16
  168.         dec ctr2
  169.         jnz luup2
  170.         add eax,8*(6+8+2+6)
  171.         dec ctr1
  172.         jnz luup1
  173.         call _PageFlip1
  174.         popad
  175.         ret
  176.  
  177. Shoo:
  178.         ; esi = new message
  179.         pushad
  180.         mov eax,0
  181.         call _ScrClr
  182.         mov eax,_VDispX
  183.         mov edx,_VDispY
  184.         add eax,64
  185.         add edx,16
  186.         mov edi,_ScrBase
  187.         mov ebx,offset head
  188.         call _PutString
  189.         add edx,16
  190.         mov ebx,esi
  191.         call _PutString
  192.         add edx,16
  193.         mov ebx,offset tail
  194.         call _PutString
  195.         ; now write the x/y button markers
  196.         mov edi,_ScrBase
  197.         mov eax,_VDispX
  198.         mov ctr1,2
  199.         mov ebx,offset xug
  200. bluup1:        
  201.         mov edx,_VDispY
  202.         add edx,100
  203.         mov ctr2,4
  204. bluup2:        
  205.         call _PutString
  206.         add ebx,6
  207.         add edx,16
  208.         dec ctr2
  209.         jnz bluup2
  210.         add eax,(6+8+2)*8
  211.         dec ctr1
  212.         jnz bluup1
  213.         
  214.         call _PageFlip0
  215.         popad
  216.         ret
  217.  
  218. CP macro a,b
  219.         mov eax,b
  220.         mov a,eax
  221.         endm  
  222.         
  223. ReleaseButton: ;wait until the pressed button is released
  224.         call RawStick
  225.         mov eax,_BUTTON
  226.         cmp _B1_A,eax
  227.         jbe ReleaseButton
  228.         cmp _B2_A,eax
  229.         jbe ReleaseButton
  230.         cmp _B1_B,eax
  231.         jbe ReleaseButton
  232.         cmp _B2_B,eax
  233.         jbe ReleaseButton
  234.         ret
  235.               
  236.         
  237. MIStick: ; main joystick initialization
  238.         pushad
  239.         
  240.         ; check lower right corner first
  241.         ; to get maximum poll times
  242.         mov esi,offset dnright
  243.         call Shoo
  244. rednright:        
  245.         call RawStick
  246.         call Shuu
  247.         CP A_XRIGHT,_JX_A
  248.         mov ebx,eax
  249.         CP A_YDOWN,_JY_A
  250.         cmp ebx,eax
  251.         ja alto1
  252.         mov ebx,eax
  253. alto1:        
  254.         CP B_XRIGHT,_JX_B
  255.         cmp ebx,eax
  256.         ja alto2
  257.         mov ebx,eax
  258. alto2:         
  259.         CP B_YDOWN,_JY_B
  260.         cmp ebx,eax
  261.         ja alto3
  262.         mov ebx,eax
  263. alto3:  lea eax,[ebx*2]
  264.         cmp _B1_A,eax
  265.         jbe doned
  266.         cmp _B2_A,eax
  267.         jbe doned
  268.         cmp _B1_B,eax
  269.         jbe doned
  270.         cmp _B2_B,eax
  271.         jnbe rednright
  272. doned:  add ebx,4
  273.         mov _POLL_TIME,ebx ; set maximum polling time to speed up things
  274.  
  275.         ; check upper left corner to get a better button threshold
  276.         mov esi,offset upleft
  277.         call Shoo
  278.         call ReleaseButton
  279. reupleft:        
  280.         call RawStick
  281.         call Shuu
  282.         CP A_XLEFT,_JX_A
  283.         mov ebx,eax
  284.         CP A_YUP,_JY_A
  285.         cmp ebx,eax
  286.         jb basso1
  287.         mov ebx,eax
  288. basso1:        
  289.         CP B_XLEFT,_JX_B
  290.         cmp ebx,eax
  291.         jb basso2
  292.         mov ebx,eax
  293. basso2:         
  294.         CP B_YUP,_JY_B
  295.         cmp ebx,eax
  296.         jb basso3
  297.         mov ebx,eax
  298. basso3: shl ebx,1 ; keep a good margin 
  299.         add ebx,4 ; & set new minimum button threshold
  300.         mov _BUTTON,ebx
  301.         cmp _B1_A,ebx
  302.         jbe doneu
  303.         cmp _B2_A,ebx
  304.         jbe doneu
  305.         cmp _B1_B,ebx
  306.         jbe doneu
  307.         cmp _B2_B,ebx
  308.         jnbe reupleft
  309. doneu:  
  310.         ; check central positions to centrate the x-y thresholds
  311.         mov esi,offset center
  312.         call Shoo
  313.         call ReleaseButton
  314. recenter:        
  315.         call RawStick
  316.         call Shuu
  317.         CP A_XCENTER,_JX_A
  318.         CP A_YCENTER,_JY_A
  319.         CP B_XCENTER,_JX_B
  320.         CP B_YCENTER,_JY_B
  321.         mov ebx,_BUTTON
  322.         cmp _B1_A,ebx
  323.         jbe donec
  324.         cmp _B2_A,ebx
  325.         jbe donec
  326.         cmp _B1_B,ebx
  327.         jbe donec
  328.         cmp _B2_B,ebx
  329.         jnbe recenter
  330. donec:  
  331.  
  332.  
  333.         ; NOW CALIBRATE THINGS
  334.         mov eax,A_XCENTER
  335.         add eax,A_XLEFT
  336.         shr eax,1
  337.         mov A_XLEFT,eax
  338.         mov eax,B_XCENTER
  339.         add eax,B_XLEFT
  340.         shr eax,1
  341.         mov B_XLEFT,eax
  342.         
  343.         mov eax,A_YCENTER
  344.         add eax,A_YUP  
  345.         shr eax,1
  346.         mov A_YUP,eax
  347.         mov eax,B_YCENTER
  348.         add eax,B_YUP     
  349.         shr eax,1
  350.         mov B_YUP,eax
  351.         ; now set the "down right" limits
  352.         mov eax,A_XRIGHT
  353.         add eax,A_XCENTER
  354.         shr eax,1
  355.         mov A_XRIGHT,eax
  356.         mov eax,B_XRIGHT
  357.         add eax,B_XCENTER
  358.         shr eax,1
  359.         mov B_XRIGHT,eax
  360.         mov eax,A_YDOWN
  361.         add eax,A_YCENTER
  362.         shr eax,1
  363.         mov A_YDOWN,eax
  364.         mov eax,B_YDOWN
  365.         add eax,B_YCENTER
  366.         shr eax,1
  367.         mov B_YDOWN,eax
  368.         mov eax,0
  369.         call _ScrClr
  370.         call _PageFlip0
  371.         popad
  372.         ret
  373.         
  374.         
  375.         
  376.         
  377. RawStick: 
  378.            mov ecx,_POLL_TIME
  379.        mov dx,JPORT
  380.        ; azzera
  381.            xor ebx,ebx
  382.            mov _JX_A,ebx
  383.            mov _JY_A,ebx
  384.            mov _JX_B,ebx
  385.            mov _JY_B,ebx
  386.            mov _B1_A,ebx
  387.            mov _B2_A,ebx
  388.            mov _B1_B,ebx
  389.            mov _B2_B,ebx
  390.            mov al,0FFh ; call me paranoid :)
  391.        cli
  392.        out dx,al ; trigger RCs
  393.  
  394. girastick:
  395.        in al,dx ; leggi lo stato delle linee del joystick
  396.        ; aggiorna i contatori
  397.        shr al,1
  398.            adc _JX_A,ebx
  399.        shr al,1
  400.            adc _JY_A,ebx
  401.        shr al,1
  402.            adc _JX_B,ebx
  403.        shr al,1
  404.            adc _JY_B,ebx
  405.        shr al,1
  406.            adc _B1_A,ebx
  407.        shr al,1
  408.            adc _B2_A,ebx
  409.        shr al,1
  410.            adc _B1_B,ebx
  411.        shr al,1
  412.            adc _B2_B,ebx
  413.            dec ecx
  414.            jne girastick
  415. stickdone:           
  416.        sti
  417.        ret
  418.  
  419.         ; read stick table
  420. RStick  dd offset MRStick,offset snone,offset snone,offset snone
  421.  
  422.         public _ReadStick
  423. _ReadStick:
  424.         jmp [esi*4+RStick]
  425.         
  426.         ; IN:   ESI = STICK DEVICE GROUP
  427.         ; OUT:  EAX = STICK BITS for joystick 0,1
  428.         ;       EDX = STICK BITS for joystick 2,3
  429.         ;
  430.         ; AX            = STICK0 
  431.         ; EAX high word = STICK1
  432.         ; DX            = STICK2
  433.         ; EDX high word = STICK3
  434.         ; Every joystick is described by 16 bits
  435.         ; (it includes 3D motion and 3D rotation plus four buttons)
  436.         ; bit  meaning
  437.         ;   0  UP 
  438.         ;   1  DOWN 
  439.         ;   2  LEFT 
  440.         ;   3  RIGHT 
  441.         ;   4  FORWARD 
  442.         ;   5  BACKWARD
  443.         ;   6  TURN_UP      = rotate forward-->up
  444.         ;   7  TURN_DOWN    = rotate forward-->down
  445.         ;   8  TURN_LEFT    = rotate forward-->left
  446.         ;   9  TURN_RIGHT   = rotate forward-->right
  447.         ;  10  ROLL_LEFT    = rotate up-->left
  448.         ;  11  ROLL_RIGHT   = rotate up-->right
  449.         ;  12  BUTTON_0 
  450.         ;  13  BUTTON_1 
  451.         ;  14  BUTTON_2 
  452.         ;  15  BUTTON_3
  453.         
  454. J_UP        =1
  455. J_DOWN      =2
  456. J_LEFT      =4
  457. J_RIGHT     =8
  458. J_FORWARD   =16
  459. J_BACKWARD  =32
  460. J_TUP       =64
  461. J_TDOWN     =128
  462. J_TLEFT     =256
  463. J_TRIGHT    =512
  464. J_RLEFT     =1024
  465. J_RRIGHT    =2048
  466. J_B0        =4096
  467. J_B1        =8192
  468. J_B2        =16384
  469. J_B3        =32768
  470. UPPER_STICK =65536
  471.         
  472. MRStick : ; read main joysticks
  473.         push ebx
  474.         push ecx
  475.         call RawStick        
  476.         ; x axis translation raw->logical
  477.         mov ebx,_JX_A       
  478.         mov eax,J_UP+J_LEFT+((J_LEFT+J_UP)*UPPER_STICK)
  479.         cmp ebx,A_XLEFT
  480.         jb done_xa
  481.         xor al,J_LEFT
  482.         cmp ebx,A_XRIGHT
  483.         jb done_xa
  484.         or al,J_RIGHT
  485. done_xa:
  486.         ; y axis translation raw->logical
  487.         mov ebx,_JY_A
  488.         cmp ebx,A_YUP
  489.         jb done_ya
  490.         xor al,J_UP
  491.         cmp ebx,A_YDOWN
  492.         jb done_ya
  493.         or al,J_DOWN
  494. done_ya: 
  495.         ; traduzione pulsanti  1= pressed 0 = not pressed
  496.         mov edx,_BUTTON
  497.         cmp _B1_A,edx
  498.         ja nob1a
  499.         or ax,J_B0
  500. nob1a:  
  501.         cmp _B2_A,edx
  502.         ja nob2a
  503.         or ax,J_B1
  504. nob2a:  ; NOW TEST SECOND JOYSTICK
  505.         mov ebx,_JX_B
  506.         cmp ebx,B_XLEFT
  507.         jb done_xb
  508.         xor eax,UPPER_STICK*J_LEFT
  509.         cmp ebx,B_XRIGHT
  510.         jb done_xb
  511.         or eax,UPPER_STICK*J_RIGHT
  512. done_xb:
  513.         ; y axis translation raw->logical
  514.         mov ebx,_JY_B
  515.         cmp ebx,B_YUP
  516.         jb done_yb
  517.         xor eax,UPPER_STICK*J_UP
  518.         cmp ebx,B_YDOWN
  519.         jb done_yb
  520.         or eax,UPPER_STICK*J_DOWN
  521. done_yb: 
  522.         ; traduzione pulsanti  1= pressed 0 = not pressed
  523.         mov edx,_BUTTON
  524.         cmp _B1_B,edx
  525.         ja nob1b
  526.         or eax,UPPER_STICK*J_B0
  527. nob1b:  
  528.         cmp _B2_B,edx
  529.         ja nob2b
  530.         or eax,UPPER_STICK*J_B1
  531. nob2b:  
  532.  
  533.         ; sticks 0,1 present
  534.         pop ecx
  535.         xor edx,edx ; sticks 2,3 are not present
  536.         pop ebx
  537.         ret
  538.         
  539. code32 ends        
  540.        END
  541.